package cn.bugstack.domain.strategy.service;

import cn.bugstack.domain.strategy.model.entity.RaffleAwardEntity;
import cn.bugstack.domain.strategy.model.entity.RaffleFactorEntity;
import cn.bugstack.domain.strategy.model.entity.RuleActionEntity;
import cn.bugstack.domain.strategy.model.valobj.RuleLogicCheckTypeVO;
import cn.bugstack.domain.strategy.model.valobj.StrategyAwardRuleModelVO;
import cn.bugstack.domain.strategy.repository.IStrategyRepository;
import cn.bugstack.domain.strategy.service.armory.IStrategyDispatch;
import cn.bugstack.domain.strategy.service.rule.chain.ILogicChain;
import cn.bugstack.domain.strategy.service.rule.chain.factory.DefaultChainFactory;
import cn.bugstack.domain.strategy.service.rule.tree.factory.DefaultTreeFactory;
import cn.bugstack.types.enums.ResponseCode;
import cn.bugstack.types.exception.AppException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

/**
 * @Title: AbstractRaffleStrategy
 * @Description: 抽奖策略抽象类
 * @author: jiangta
 * @date: 2024/10/25 下午4:23
 * @Version: 1.0
 */
@Slf4j
public abstract class AbstractRaffleStrategy implements IRaffleStrategy {

    // 策略仓储服务 -> domain层像一个大厨，仓储层提供米面粮油
    protected IStrategyRepository strategyRepository;
    // 策略调度服务 -> 只负责抽奖处理，通过新增接口的方式，隔离职责，不需要使用方关心或者调用抽奖的初始化
    protected IStrategyDispatch strategyDispatch;
    // 抽奖的责任链 -> 从抽奖的规则中，解耦出前置规则为责任链处理
    protected DefaultChainFactory defaultChainFactory;
    // 抽奖的决策树 -> 负责抽奖中到抽奖后的规则过滤，如抽奖到A奖品ID，之后要做次数的判断和库存的扣减等。
    protected DefaultTreeFactory defaultTreeFactory;

    public AbstractRaffleStrategy(IStrategyRepository strategyRepository, IStrategyDispatch strategyDispatch
            , DefaultChainFactory defaultChainFactory, DefaultTreeFactory defaultTreeFactory) {
        this.strategyRepository = strategyRepository;
        this.strategyDispatch = strategyDispatch;
        this.defaultChainFactory = defaultChainFactory;
        this.defaultTreeFactory = defaultTreeFactory;
    }

    @Override
    public RaffleAwardEntity performRaffle(RaffleFactorEntity raffleFactorEntity) {
        //1.参数校验
        String userId = raffleFactorEntity.getUserId();
        Long strategyId = raffleFactorEntity.getStrategyId();
        if (StringUtils.isBlank(userId) || null == strategyId) {
            throw new AppException(ResponseCode.ILLEGAL_PARAMETER);
        }

//        //2。责任链处理抽奖
//        ILogicChain iLogicChain = defaultChainFactory.openLogicChain(strategyId);
//        Integer awardId = iLogicChain.logic(userId, strategyId);
        //2.责任链抽奖计算【这步拿到的是初步的抽奖id，之后需要根据ID处理抽奖】注意：黑名单，权重等非默认抽奖的直接返回抽奖结果
        DefaultChainFactory.StrategyAwardVO chainStrategyAwardVO = raffleLogicChain(userId, strategyId);
        log.info("抽奖策略计算-责任链 {} {} {} {}", userId, strategyId, chainStrategyAwardVO.getAwardId(), chainStrategyAwardVO.getLogicModel());
        if (!DefaultChainFactory.LogicModel.RULE_DEFAULT.getCode().equals(chainStrategyAwardVO.getLogicModel())) {
            return RaffleAwardEntity.builder()
                    .awardId(chainStrategyAwardVO.getAwardId())
                    .build();
        }

        //3.规则树抽奖过滤【奖品ID，会根据抽奖次数判断，库存判断，兜底判断返回最终的可获得奖品信息】
        DefaultTreeFactory.StrategyAwardVO treeStrategyAwardVO = raffleLogicTree(userId, strategyId, chainStrategyAwardVO.getAwardId());
        log.info("抽奖策略计算-规则树 {} {} {} {}", userId, strategyId, treeStrategyAwardVO.getAwardId(), treeStrategyAwardVO.getAwardRuleValue());

        // 4. 返回抽奖结果
        return RaffleAwardEntity.builder()
                .awardId(treeStrategyAwardVO.getAwardId())
                .awardConfig(treeStrategyAwardVO.getAwardRuleValue())
                .build();

//        //2.策略查询
//        StrategyEntity strategyEntity = strategyRepository.queryStrategyEntityByStrategyId(strategyId);
//
//        //3.抽奖前-规则过滤
//        RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> ruleActionEntity = this.doCheckRaffleBeforeLoigc(raffleFactorEntity, strategyEntity.ruleModels());
//        if (ruleActionEntity.getCode().equals(RuleLogicCheckTypeVO.TAKE_OVER.getCode())) {
//            if (DefaultLogicFactory.LogicModel.RULE_BLACKLIST.getCode().equals(ruleActionEntity.getRuleModel())) {
//                //黑名单返回固定的奖品 ID
//                return RaffleAwardEntity.builder().awardId(ruleActionEntity.getData().getAwardId()).build();
//            } else if (DefaultLogicFactory.LogicModel.RULE_WIGHT.getCode().equals(ruleActionEntity.getRuleModel())) {
//                //权重抽奖
//                RuleActionEntity.RaffleBeforeEntity raffleBeforeEntity = ruleActionEntity.getData();
//                String ruleWeightValueKey = raffleBeforeEntity.getRuleWeightValueKey();
//                Integer randomAwardId = strategyDispatch.getRandomAwardId(strategyId, ruleWeightValueKey);
//                return RaffleAwardEntity.builder().awardId(randomAwardId).build();
//            }
//        }
//
//        //4.默认抽奖流程
//        Integer awardId = strategyDispatch.getRandomAwardId(strategyId);

        // //5.查询奖品规则【抽奖中（拿到奖品时，过滤规则），抽奖后（扣减完奖品库存后过滤，抽奖中拦截和无库存则走兜底）】
        // StrategyAwardRuleModelVO strategyAwardRuleModelVO = strategyRepository.queryStrategyAwardRuleModel(strategyId, awardId);

        // //6.抽奖中-规则过滤
        // RuleActionEntity<RuleActionEntity.RaffleCenterEntity> ruleActionEntityCenter =
        //         this.doCheckRaffleCenterLoigc(RaffleFactorEntity.builder().strategyId(strategyId)
        //                 .userId(userId)
        //                 .awardId(awardId).build(), strategyAwardRuleModelVO.raffleCenterRuleModelList());
        // if (RuleLogicCheckTypeVO.TAKE_OVER.getCode().equals(ruleActionEntityCenter.getCode())) {
        //     log.info("【临时日志】中奖中规则拦截，通过抽奖后规则 rule_luck_award 走兜底奖励。");
        //     return RaffleAwardEntity.builder().awardDesc("中奖中规则拦截，通过抽奖后规则 rule_luck_award 走兜底奖励。").build();
        // }
//        return RaffleAwardEntity.builder()
//                .awardId(awardId).build();
    }

//    /**
//     * 抽奖前逻辑处理
//     *
//     * @param raffleFactorEntity
//     * @param ruleModels
//     * @return
//     */
//    protected abstract RuleActionEntity<RuleActionEntity.RaffleBeforeEntity> doCheckRaffleBeforeLoigc(RaffleFactorEntity raffleFactorEntity, String... ruleModels);

//    /**
//     * 抽奖中逻辑处理
//     *
//     * @param raffleFactorEntity
//     * @param ruleModels
//     * @return
//     */
//    protected abstract RuleActionEntity<RuleActionEntity.RaffleCenterEntity> doCheckRaffleCenterLoigc(RaffleFactorEntity raffleFactorEntity, String... ruleModels);

    /**
     * 抽奖计算，责任链抽象方法
     *
     * @param userId     用户ID
     * @param strategyId 策略ID
     * @return 奖品ID
     */
    protected abstract DefaultChainFactory.StrategyAwardVO raffleLogicChain(String userId, Long strategyId);

    /**
     * 抽奖结果过滤，决策树抽象方法
     *
     * @param userId
     * @param strategyId
     * @param awardId
     * @return
     */
    protected abstract DefaultTreeFactory.StrategyAwardVO raffleLogicTree(String userId, Long strategyId, Integer awardId);
}